/*
 * Copyright (c) Tony Bybell 1999-2014.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 */

#include "globals.h"

#ifndef ANALYZER_H
#define ANALYZER_H

#include <gtk/gtk.h>
#include <stdlib.h>
#include "vlist.h"
#include "debug.h"

#ifdef AET2_IS_PRESENT
#define WAVE_ARRAY_SUPPORT
#endif

/* struct Node bitfield widths */
#define WAVE_VARXT_WIDTH (16)
#define WAVE_VARXT_MAX_ID ((1 << WAVE_VARXT_WIDTH) - 1)
#define WAVE_VARDT_WIDTH (6)
#define WAVE_VARDIR_WIDTH (3)
#define WAVE_VARTYPE_WIDTH (6)

typedef struct _SearchProgressData
{
    GtkWidget *window;
    GtkWidget *pbar;
    int timer; /* might be used later.. */
    gfloat value, oldvalue;
} SearchProgressData;

#define BITATTRIBUTES_MAX 32768

typedef struct ExpandInfo *eptr;
typedef struct ExpandReferences *exptr;
typedef struct Node *nptr;
typedef struct HistEnt *hptr;
typedef struct Bits *bptr;
typedef struct VectorEnt *vptr;
typedef struct BitVector *bvptr;
typedef struct BitAttributes *baptr;

typedef unsigned long Ulong;
typedef unsigned int Uint;

enum TraceReorderMode
{
    TR_SORT_INS,
    TR_SORT_NORM,
    TR_SORT_LEX,
    TR_SORT_RVS
};

/* vvv   Bit representation   vvv */

enum AnalyzerBits
{
    AN_0,
    AN_X,
    AN_Z,
    AN_1,
    AN_H,
    AN_U,
    AN_W,
    AN_L,
    AN_DASH,
    AN_RSV9,
    AN_RSVA,
    AN_RSVB,
    AN_RSVC,
    AN_RSVD,
    AN_RSVE,
    AN_RSVF,
    AN_COUNT
};
#define AN_NORMAL \
    { \
        AN_0, AN_X, AN_Z, AN_1, AN_H, AN_U, AN_W, AN_L, AN_DASH, AN_DASH, AN_DASH, AN_DASH, \
            AN_DASH, AN_DASH, AN_DASH, AN_DASH \
    }
#define AN_INVERSE \
    { \
        AN_1, AN_X, AN_Z, AN_0, AN_L, AN_U, AN_W, AN_H, AN_DASH, AN_DASH, AN_DASH, AN_DASH, \
            AN_DASH, AN_DASH, AN_DASH, AN_DASH \
    }

#define AN_MSK \
    (AN_COUNT - 1) /* max index into AN_STR, AN_COUNT *must* be a power of two unless logic AND \
                      with AN_MSK is changed */

/* positional ascii 0123456789ABCDEF, question marks should not happen unless something slips
 * through the cracks as AN_RSVA to AN_RSVF are reserved */
#define AN_STR "0xz1huwl-???????"
#define AN_STR_INV "1xz0luwh-???????"

#define AN_USTR "0XZ1HUWL-???????"
#define AN_USTR_INV "1XZ0LUWH-???????"

/* for writing out 4 state formats (read GHW, write LXT) */
#define AN_STR4ST "0xz11xz0xxxxxxxx"
#define AN_USTR4ST "0XZ11XZ0XXXXXXXX"

/* for hex/oct conversion in baseconvert.c */
#define AN_HEX_STR "0123456789ABCDEFxzwu-XZWU"
#define AN_OCT_STR "01234567xzwu-"

/* now the recoded "extra" values... */
#define RCV_X (1 | (0 << 1))
#define RCV_Z (1 | (1 << 1))
#define RCV_H (1 | (2 << 1))
#define RCV_U (1 | (3 << 1))
#define RCV_W (1 | (4 << 1))
#define RCV_L (1 | (5 << 1))
#define RCV_D (1 | (6 << 1))

#define RCV_STR "xzhuwl-?"
/*               01234567 */

/* ^^^   Bit representation   ^^^ */

#define WAVE_HAS_H_DOUBLE

#ifdef WAVE_USE_STRUCT_PACKING
#pragma pack(push)
#pragma pack(1)
#endif

typedef struct HistEnt
{
    hptr next; /* next transition in history */

    union
    {
        unsigned char h_val; /* value: AN_STR[val] or AnalyzerBits which correspond */
        char *h_vector; /* pointer to a whole vector of h_val type bits */
#ifdef WAVE_HAS_H_DOUBLE
        double h_double;
#endif
    } v;

    TimeType time; /* time of transition */
    unsigned char flags; /* so far only set on glitch/real condition */
} HistEnt;

#ifdef WAVE_USE_STRUCT_PACKING
#pragma pack(pop)
#endif

enum HistEntFlagBits
{
    HIST_GLITCH_B,
    HIST_REAL_B,
    HIST_STRING_B
};

#define HIST_GLITCH (1 << HIST_GLITCH_B)
#define HIST_REAL (1 << HIST_REAL_B)
#define HIST_STRING (1 << HIST_STRING_B)

#ifdef WAVE_USE_STRUCT_PACKING
#pragma pack(push)
#pragma pack(1)
#endif

typedef struct VectorEnt
{
    TimeType time;
    vptr next;
    unsigned char flags; /* so far only set on strings */
    unsigned char v[]; /* C99 */
} VectorEnt;

#ifdef WAVE_USE_STRUCT_PACKING
#pragma pack(pop)
#endif

#define MAX_HISTENT_TIME ((TimeType)(~((ULLDescriptor(-1)) << (sizeof(TimeType) * 8 - 1))))

typedef struct ExpandInfo /* only used when expanding atomic vex.. */
{
    nptr *narray;
    int msb, lsb;
    int width;
} ExpandInfo;

typedef struct ExpandReferences
{
    nptr parent; /* which atomic vec we expanded from */
    int parentbit; /* which bit from that atomic vec */
    int actual; /* bit number to be used in [] */
    int refcnt;
} ExpandReferences;

#ifdef WAVE_USE_STRUCT_PACKING
#pragma pack(push)
#pragma pack(1)
#endif

struct Node
{
    exptr expansion; /* indicates which nptr this node was expanded from (if it was expanded at all)
                        and (when implemented) refcnts */
    char *nname; /* ascii name of node */
    HistEnt head; /* first entry in transition history */
    hptr curr; /* ptr. to current history entry */

    hptr *harray; /* fill this in when we make a trace.. contains  */
    /*  a ptr to an array of histents for bsearching */
    union
    {
        struct fac *mvlfac; /* for use with mvlsim aets */
        struct vlist_packer_t *mvlfac_packer_vlist;
        struct vlist_t *mvlfac_vlist;
        char *value; /* for use when unrolling ae2 values */
    } mv; /* anon union is a gcc extension so use mv instead.  using this union avoids crazy casting
             warnings */

    int msi, lsi; /* for 64-bit, more efficient than having as an external struct ExtNode*/

    int numhist; /* number of elements in the harray */

#ifdef WAVE_ARRAY_SUPPORT
    unsigned int array_height, this_row;
#endif

    unsigned varxt : WAVE_VARXT_WIDTH; /* reference inside subvar_pnt[] */
    unsigned vardt : WAVE_VARDT_WIDTH; /* see nodeVarDataType, this is an internal value */
    unsigned vardir : WAVE_VARDIR_WIDTH; /* see nodeVarDir, this is an internal value (currently
                                            used only by extload and FST) */
    unsigned vartype : WAVE_VARTYPE_WIDTH; /* see nodeVarType, this is an internal value */

    unsigned extvals : 1; /* was formerly a pointer to ExtNode "ext", now simply a flag */
};

#ifdef WAVE_USE_STRUCT_PACKING
#pragma pack(pop)
#endif

#define WAVE_NODEVARTYPE_STR \
    static const char *vartype_strings[] = { \
        "",        "event", "integer", "parm",   "real",     "real_parm", "reg",    "supply0", \
        "supply1", "time",  "tri",     "triand", "trior",    "trireg",    "tri0",   "tri1", \
        "wand",    "wire",  "wor",     "array",  "realtime", "port",      "string", "bit", \
        "logic",   "int",   "s_int",   "l_int",  "byte",     "enum",      "s_real", "signal", \
        "var",     "const", "file",    "memory", "net",      "alias",     "missing"};

enum nodeVarType
{
    ND_UNSPECIFIED_DEFAULT = 0,

    ND_VCD_EVENT = 1,
    ND_VCD_INTEGER = 2,
    ND_VCD_PARAMETER = 3,
    ND_VCD_REAL = 4,
    ND_VCD_REAL_PARAMETER = 5,
    ND_VCD_REG = 6,
    ND_VCD_SUPPLY0 = 7,
    ND_VCD_SUPPLY1 = 8,
    ND_VCD_TIME = 9,
    ND_VCD_TRI = 10,
    ND_VCD_TRIAND = 11,
    ND_VCD_TRIOR = 12,
    ND_VCD_TRIREG = 13,
    ND_VCD_TRI0 = 14,
    ND_VCD_TRI1 = 15,
    ND_VCD_WAND = 16,
    ND_VCD_WIRE = 17,
    ND_VCD_WOR = 18,
    ND_VCD_ARRAY = 19, /* used to define the rownum (index) port on the array */
    ND_VCD_REALTIME = 20,

    ND_VCD_PORT = 21,
    ND_GEN_STRING = 22, /* generic string type */

    ND_SV_BIT = 23, /* SV types */
    ND_SV_LOGIC = 24,
    ND_SV_INT = 25,
    ND_SV_SHORTINT = 26,
    ND_SV_LONGINT = 27,
    ND_SV_BYTE = 28,
    ND_SV_ENUM = 29,
    ND_SV_SHORTREAL = 30,

    ND_VHDL_SIGNAL = 31,
    ND_VHDL_VARIABLE = 32,
    ND_VHDL_CONSTANT = 33,
    ND_VHDL_FILE = 34,
    ND_VHDL_MEMORY = 35,

    ND_GEN_NET = 36, /* used for AE2 */
    ND_GEN_ALIAS = 37,
    ND_GEN_MISSING = 38,

    ND_VARTYPE_MAX = 38
    /* if this exceeds 63, need to update struct Node's "unsigned vartype : 6" declaration */
};

#define WAVE_NODEVARDATATYPE_STR \
    static const char *vardatatype_strings[] = {"", \
                                                "boolean", \
                                                "bit", \
                                                "bit_vec", \
                                                "ulogic", \
                                                "ulogic_v", \
                                                "logic", \
                                                "logic_v", \
                                                "unsigned", \
                                                "signed", \
                                                "integer", \
                                                "real", \
                                                "natural", \
                                                "positive", \
                                                "time", \
                                                "char", \
                                                "string"};

enum nodeVarDataType
{
    ND_VDT_NONE = 0,

    ND_VDT_VHDL_BOOLEAN = 1,
    ND_VDT_VHDL_BIT = 2,
    ND_VDT_VHDL_BIT_VECTOR = 3,
    ND_VDT_VHDL_STD_ULOGIC = 4,
    ND_VDT_VHDL_STD_ULOGIC_VECTOR = 5,
    ND_VDT_VHDL_STD_LOGIC = 6,
    ND_VDT_VHDL_STD_LOGIC_VECTOR = 7,
    ND_VDT_VHDL_UNSIGNED = 8,
    ND_VDT_VHDL_SIGNED = 9,
    ND_VDT_VHDL_INTEGER = 10,
    ND_VDT_VHDL_REAL = 11,
    ND_VDT_VHDL_NATURAL = 12,
    ND_VDT_VHDL_POSITIVE = 13,
    ND_VDT_VHDL_TIME = 14,
    ND_VDT_VHDL_CHARACTER = 15,
    ND_VDT_VHDL_STRING = 16,

    ND_VDT_MAX = 16
    /* if this exceeds 63, need to update struct Node's "unsigned vardt : 6" declaration */
};

#define WAVE_NODEVARDIR_STR static const char *vardir_strings[] = {"", "I", "O", "IO", "B", "L"};

enum nodeVarDir
{
    ND_DIR_IMPLICIT = 0,
    ND_DIR_IN = 1,
    ND_DIR_OUT = 2,
    ND_DIR_INOUT = 3,
    ND_DIR_BUFFER = 4,
    ND_DIR_LINKAGE = 5,

    ND_DIR_MAX = 5,
    ND_DIR_UNSPECIFIED = 6
    /* if ND_DIR_MAX exceeds 7, need to update struct Node's "unsigned vardir : 3" declaration */
};

typedef uint64_t TraceFlagsType;
#define TRACEFLAGSSCNFMT SCNx64
#define TRACEFLAGSPRIFMT PRIx64
#define TRACEFLAGSPRIuFMT PRIu64

typedef struct BitAttributes
{
    TimeType shift;
    TraceFlagsType flags;
} BitAttributes;

#ifdef WAVE_USE_STRUCT_PACKING
#pragma pack(push)
#pragma pack(1)
#endif

typedef struct Bits
{
    char *name; /* name of this vector of bits   */
    int nnbits; /* number of bits in this vector */
    baptr attribs; /* for keeping track of combined timeshifts and inversions (and for savefile) */

    nptr nodes[]; /* C99 pointers to the bits (nodes)  */
} Bits;

#ifdef WAVE_USE_STRUCT_PACKING
#pragma pack(pop)
#endif

#ifdef WAVE_USE_STRUCT_PACKING
#pragma pack(push)
#pragma pack(1)
#endif

typedef struct BitVector
{
    bvptr transaction_cache; /* for TR_TTRANSLATED traces */
    bvptr transaction_chain; /* for TR_TTRANSLATED traces */
    nptr transaction_nd; /* for TR_TTRANSLATED traces */

    char *bvname; /* name of this vector of bits           */
    int nbits; /* number of bits in this vector         */
    int numregions; /* number of regions that follow         */
    bptr bits; /* pointer to Bits structs for save file */
    vptr vectors[]; /* C99 pointers to the vectors           */
} BitVector;

#ifdef WAVE_USE_STRUCT_PACKING
#pragma pack(pop)
#endif

typedef struct
{
    TimeType first; /* beginning time of trace */
    TimeType last; /* end time of trace */
    TimeType start; /* beginning time of trace on screen */
    TimeType end; /* ending time of trace on screen */
    TimeType marker;
    TimeType prevmarker; /* from last drawmarker()	        */
    TimeType resizemarker; /* from last MaxSignalLength()          */
    TimeType resizemarker2; /* from 2nd last MaxSignalLength()      */
    TimeType lmbcache; /* initial marker pos                   */
    TimeType timecache; /* to get around floating pt limitation */
    TimeType laststart; /* caches last set value                */
    TimeType baseline; /* baseline (center button) marker      */

    gdouble zoom; /* current zoom  */
    gdouble prevzoom; /* for zoom undo */
} Times;

typedef struct TraceEnt *Trptr;

typedef struct
{
    int total; /* total number of traces */
    int visible; /* total number of (uncollapsed) traces */
    Trptr first; /* ptr. to first trace in list */
    Trptr last; /* end of list of traces */
    Trptr buffer; /* cut/copy buffer of traces */
    Trptr bufferlast; /* last element of bufferchain */
    int buffercount; /* number of traces in buffer */

    unsigned dirty : 1; /* to notify Tcl that traces were added/deleted/moved */
} Traces;

typedef struct
{
    Trptr buffer; /* cut/copy buffer of traces */
    Trptr bufferlast; /* last element of bufferchain */
    int buffercount; /* number of traces in buffer */
} TempBuffer;

typedef struct TraceEnt
{
    Trptr t_next; /* doubly linked list of traces */
    Trptr t_prev;
    Trptr t_grp; /* pointer to group I'm in */
    Trptr t_match; /* If group begin pointer to group end and visa versa */

    char *name; /* current name */
    char *name_full; /* full name */
    char *asciivalue; /* value that marker points to */
    char *transaction_args; /* for TR_TTRANSLATED traces */
    TimeType asciitime; /* time this value corresponds with */
    TimeType shift; /* offset added to all entries in the trace */
    TimeType shift_drag; /* cached initial offset for CTRL+LMB drag on highlighted */

    double d_minval, d_maxval; /* cached value for when auto scaling is turned off */
    int d_num_ext; /* need to regen if differs from current in analog! */

    union
    {
        nptr nd; /* what makes up this trace */
        bvptr vec;
    } n;

    TraceFlagsType flags; /* see def below in TraceEntFlagBits */
    TraceFlagsType cached_flags; /* used for tcl for saving flags during cut and paste */

    int f_filter; /* file filter */
    int p_filter; /* process filter */
    int t_filter; /* transaction process filter */
    int e_filter; /* enum filter (from FST) */

    unsigned int t_color; /* trace color index */
    unsigned char t_fpdecshift; /* for fixed point decimal */

    unsigned is_cursor : 1; /* set to mark a cursor trace */
    unsigned is_alias : 1; /* set when it's an alias (safe to free t->name then) */
    unsigned is_depacked : 1; /* set when it's been depacked from a compressed entry (safe to free
                                 t->name then) */
    unsigned vector : 1; /* 1 if bit vector, 0 if node */
    unsigned shift_drag_valid : 1; /* qualifies shift_drag above */
    unsigned interactive_vector_needs_regeneration : 1; /* for interactive VCDs */
    unsigned minmax_valid : 1; /* for d_minval, d_maxval */
    unsigned is_sort_group : 1; /* only used for sorting purposes */
    unsigned t_filter_converted : 1; /* used to mark that data conversion already occurred if
                                        t_filter != 0*/
} TraceEnt;

enum TraceEntFlagBits
{
    TR_HIGHLIGHT_B,
    TR_HEX_B,
    TR_DEC_B,
    TR_BIN_B,
    TR_OCT_B,
    TR_RJUSTIFY_B,
    TR_INVERT_B,
    TR_REVERSE_B,
    TR_EXCLUDE_B,
    TR_BLANK_B,
    TR_SIGNED_B,
    TR_ASCII_B,
    TR_COLLAPSED_B,
    TR_FTRANSLATED_B,
    TR_PTRANSLATED_B,
    TR_ANALOG_STEP_B,
    TR_ANALOG_INTERPOLATED_B,
    TR_ANALOG_BLANK_STRETCH_B,
    TR_REAL_B,
    TR_ANALOG_FULLSCALE_B,
    TR_ZEROFILL_B,
    TR_ONEFILL_B,
    TR_CLOSED_B,
    TR_GRP_BEGIN_B,
    TR_GRP_END_B,
    TR_BINGRAY_B,
    TR_GRAYBIN_B,
    TR_REAL2BITS_B,
    TR_TTRANSLATED_B,
    TR_POPCNT_B,
    TR_FPDECSHIFT_B,
    TR_TIME_B,
    TR_ENUM_B,
    TR_CURSOR_B,
    TR_FFO_B,

    TR_RSVD_B /* for use internally such as temporary caching of highlighting, not for use in traces
               */
};

#define TR_HIGHLIGHT (UINT64_C(1) << TR_HIGHLIGHT_B)
#define TR_HEX (UINT64_C(1) << TR_HEX_B)
#define TR_ASCII (UINT64_C(1) << TR_ASCII_B)
#define TR_DEC (UINT64_C(1) << TR_DEC_B)
#define TR_BIN (UINT64_C(1) << TR_BIN_B)
#define TR_OCT (UINT64_C(1) << TR_OCT_B)
#define TR_RJUSTIFY (UINT64_C(1) << TR_RJUSTIFY_B)
#define TR_INVERT (UINT64_C(1) << TR_INVERT_B)
#define TR_REVERSE (UINT64_C(1) << TR_REVERSE_B)
#define TR_EXCLUDE (UINT64_C(1) << TR_EXCLUDE_B)
#define TR_BLANK (UINT64_C(1) << TR_BLANK_B)
#define TR_SIGNED (UINT64_C(1) << TR_SIGNED_B)
#define TR_ANALOG_STEP (UINT64_C(1) << TR_ANALOG_STEP_B)
#define TR_ANALOG_INTERPOLATED (UINT64_C(1) << TR_ANALOG_INTERPOLATED_B)
#define TR_ANALOG_BLANK_STRETCH (UINT64_C(1) << TR_ANALOG_BLANK_STRETCH_B)
#define TR_REAL (UINT64_C(1) << TR_REAL_B)
#define TR_ANALOG_FULLSCALE (UINT64_C(1) << TR_ANALOG_FULLSCALE_B)
#define TR_ZEROFILL (UINT64_C(1) << TR_ZEROFILL_B)
#define TR_ONEFILL (UINT64_C(1) << TR_ONEFILL_B)
#define TR_CLOSED (UINT64_C(1) << TR_CLOSED_B)

#define TR_GRP_BEGIN (UINT64_C(1) << TR_GRP_BEGIN_B)
#define TR_GRP_END (UINT64_C(1) << TR_GRP_END_B)
#define TR_GRP_MASK (TR_GRP_BEGIN | TR_GRP_END)

#define TR_BINGRAY (UINT64_C(1) << TR_BINGRAY_B)
#define TR_GRAYBIN (UINT64_C(1) << TR_GRAYBIN_B)
#define TR_GRAYMASK (TR_BINGRAY | TR_GRAYBIN)

#define TR_REAL2BITS (UINT64_C(1) << TR_REAL2BITS_B)

#define TR_NUMMASK \
    (TR_ASCII | TR_HEX | TR_DEC | TR_BIN | TR_OCT | TR_SIGNED | TR_REAL | TR_TIME | TR_ENUM)
#define TR_ATTRIBS (TR_RJUSTIFY | TR_INVERT | TR_REVERSE | TR_EXCLUDE | TR_POPCNT | TR_FFO)

#define TR_COLLAPSED (UINT64_C(1) << TR_COLLAPSED_B)
#define TR_ISCOLLAPSED (TR_BLANK | TR_COLLAPSED)

#define TR_FTRANSLATED (UINT64_C(1) << TR_FTRANSLATED_B)
#define TR_PTRANSLATED (UINT64_C(1) << TR_PTRANSLATED_B)
#define TR_TTRANSLATED (UINT64_C(1) << TR_TTRANSLATED_B)

#define TR_POPCNT (UINT64_C(1) << TR_POPCNT_B)
#define TR_FPDECSHIFT (UINT64_C(1) << TR_FPDECSHIFT_B)

#define TR_TIME (UINT64_C(1) << TR_TIME_B)
#define TR_ENUM (UINT64_C(1) << TR_ENUM_B)

#define TR_CURSOR (UINT64_C(1) << TR_CURSOR_B)
#define TR_FFO (UINT64_C(1) << TR_FFO_B)

#define TR_ANALOGMASK (TR_ANALOG_STEP | TR_ANALOG_INTERPOLATED)

#define TR_RSVD (UINT64_C(1) << TR_RSVD_B)

Trptr GiveNextTrace(Trptr t);
Trptr GivePrevTrace(Trptr t);
int UpdateTracesVisible(void);

void DisplayTraces(int val);
int AddNodeTraceReturn(nptr nd, char *aliasname, Trptr *tret);
int AddNode(nptr nd, char *aliasname);
int AddNodeUnroll(nptr nd, char *aliasname);
int AddVector(bvptr vec, char *aliasname);
int AddBlankTrace(char *commentname);
int InsertBlankTrace(char *comment, TraceFlagsType different_flags);
void RemoveNode(nptr n);
void RemoveTrace(Trptr t, int dofree);
void FreeTrace(Trptr t);
Trptr CutBuffer(void);
void FreeCutBuffer(void);
Trptr PasteBuffer(void);
Trptr PrependBuffer(void);
int TracesReorder(int mode);
int DeleteBuffer(void);

void import_trace(nptr np);

eptr ExpandNode(nptr n);
void DeleteNode(nptr n);
nptr ExtractNodeSingleBit(nptr n, int bit);

/* hierarchy depths */
char *hier_extract(char *pnt, int levels);

/* vector matching */
char *attempt_vecmatch(char *s1, char *s2);

void updateTraceGroup(Trptr t);
int GetTraceNumber(Trptr t);
void EnsureGroupsMatch(void);

#define IsSelected(t) (t->flags & TR_HIGHLIGHT)
#define IsGroupBegin(t) (t->flags & TR_GRP_BEGIN)
#define IsGroupEnd(t) (t->flags & TR_GRP_END)
#define IsClosed(t) (t->flags & TR_CLOSED)
#define HasWave(t) (!(t->flags & (TR_BLANK | TR_ANALOG_BLANK_STRETCH)))
#define CanAlias(t) HasWave(t)
#define HasAlias(t) (t->name_full && HasWave(t))
#define IsCollapsed(t) (t->flags & TR_COLLAPSED)

unsigned IsShadowed(Trptr t);
char *GetFullName(Trptr t, int *was_packed);

void OpenTrace(Trptr t);
void CloseTrace(Trptr t);
void ClearTraces(void);
void ClearGroupTraces(Trptr t);
void MarkTraceCursor(Trptr t);

char *varxt_fix(char *s);

#endif
